/************************************************************************/
/* @file            gxPtr.h                                             */
/* @brief           Smart Ptr                                           */
/* @version         2013.11.14 johnxguo created                         */
/* @Notice          Don't mix use smart pointer and raw pointer!        */
/************************************************************************/

#ifndef __GX_PTR_H_INCLUDED__
#define __GX_PTR_H_INCLUDED__

#include "gxRef.h"

namespace gx
{
namespace base
{
template<class T>
class CGxPtr
{
public:
    CGxPtr():m_pT(NULL)
    {}
    CGxPtr(T* pT):m_pT(pT)
    {
        if (m_pT)
        {
            m_pT->AddRef();
        }
    }
    CGxPtr(const CGxPtr& gxPtr):m_pT(gxPtr.m_pT)
    {
        if (m_pT)
        {
            m_pT->AddRef();
        }
    }
    ~CGxPtr()
    {
        if (m_pT)
        {
            m_pT->Release();
        }
    }

    operator T* () const
    {
        return m_pT;
    }

    T& operator * ()
    {
        return *m_pT;
    }

    T** operator & ()
    {
        return &m_pT;
    }

    T* operator -> ()
    {
        return m_pT;
    }
    
    bool operator ! () const
    {
        return m_pT == NULL;
    }

    CGxPtr& operator = (const CGxPtr& gxPtr)
    {
        if (m_pT)
        {
            m_pT->Release();
        }

        m_pT = gxPtr.m_pT;

        if (m_pT)
        {
            m_pT->AddRef();
        }

        return *this;
    }

    CGxPtr& operator = (T* pT)
    {
        if (m_pT)
        {
            m_pT->Release();
        }

        m_pT = pT;

        if (m_pT)
        {
            m_pT->AddRef();
        }

        return *this;
    }

private:
    T* m_pT;
};

}//end namespace base
}//end namespace gx

#endif